package customer

import (
	"context"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/utils"
	"git.myscrm.cn/golang/stark/v4"
	"gorm.io/gorm"
	"time"
)

type customerGroupRepository struct {
}

func NewCustomerGroupRepository() CustomerGroupRepositoryIface {
	return &customerGroupRepository{}
}

func (c *customerGroupRepository) QueryCustomerGroupList(ctx context.Context, condition map[string]interface{}, pageInfo *utils.PageInfo, orderBy string) (int64, []*GroupListItem, error) {
	var result []*GroupListItem
	var count int64
	db := stark.MySQLConn.Get(ctx)
	condition["c.is_deleted"] = constants.IsDeletedFalse
	condition["r.is_deleted"] = constants.IsDeletedFalse
	db = db.Table(CustomerGroupPo{}.TableName() + " c").
		Joins("left join customer_group_tenant_relation r ON c.id = r.customer_group_id").
		Joins("left join common_file f ON c.common_file_uid = f.uid")

	if val, ok := condition["tenant_code_with_others"]; ok {
		db.Where("(r.tenant_code = ? or r.tenant_code = ?)", val, "all")
		delete(condition, "tenant_code_with_others")
	}

	db = db.Where(condition).Group("c.id")

	err := db.Distinct("c.id").Count(&count).Error
	if err != nil {
		return 0, nil, err
	}

	if pageInfo != nil && pageInfo.PageSize > 0 && pageInfo.Page > 0 {
		db = db.Offset((pageInfo.Page - 1) * pageInfo.PageSize).Limit(pageInfo.PageSize)
	}

	if orderBy != "" {
		db = db.Order(orderBy)
	}

	err = db.Select("c.id as id,c.title as title,c.total as total,c.is_public as is_public,c.status as status,c.common_file_uid as file_id,f.file_path as file_path,c.created_by as created_by,c.created_on as created_on,GROUP_CONCAT( r.tenant_code ) as tenant_codes").
		Find(&result).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return 0, result, nil
		}
		return 0, nil, err
	}
	return count, result, nil
}

func (c *customerGroupRepository) SaveCustomerGroup(ctx context.Context, po *CustomerGroupPo) (*CustomerGroupPo, error) {
	// 先查询是否存在，如果存在就更新，不存在就插入
	db := stark.MySQLConn.Get(ctx)
	var data CustomerGroupPo
	err := db.Table(po.TableName()).Where("id = ? and is_deleted = ?", po.ID, constants.IsDeletedFalse).First(&data).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}
	data.Title = po.Title
	data.CommonFileUid = po.CommonFileUid
	data.LandUsage = po.LandUsage
	data.LandUsageOp = po.LandUsageOp
	data.LandTitle = po.LandTitle
	data.LandTitleOp = po.LandTitleOp
	data.BuildingType = po.BuildingType
	data.BuildingTypeOp = po.BuildingTypeOp
	data.BuildingTitle = po.BuildingTitle
	data.BuildingTitleOp = po.BuildingTitleOp
	data.BidTitle = po.BidTitle
	data.BidTitleOp = po.BidTitleOp
	data.WinBidTitle = po.WinBidTitle
	data.WinBidTitleOp = po.WinBidTitleOp
	data.ModifiedOn = time.Now()
	data.ModifiedBy = po.ModifiedBy
	data.IsDeleted = constants.IsDeletedFalse
	data.IsPublic = po.IsPublic
	if data.ID == 0 {
		// 新增
		data.CreatedBy = po.CreatedBy
		data.CreatedOn = po.CreatedOn
		err = db.Table(po.TableName()).Create(&data).Error
		if err != nil {
			return nil, err
		}
	} else {
		// 更新
		err = db.Table(po.TableName()).Save(&data).Error
		if err != nil {
			return nil, err
		}
	}
	return &data, nil
}

func (c *customerGroupRepository) SaveCustomerGroupTenantRelation(ctx context.Context, po *CustomerGroupPo, tenantCode []string) error {
	// 先删除
	db := stark.MySQLConn.Get(ctx)
	err := db.Table(CustomerGroupTenantRelationPo{}.TableName()).
		Where("is_deleted = ? and customer_group_id = ?", constants.IsDeletedFalse, po.ID).
		Update("is_deleted", constants.IsDeletedTrue).
		Error
	if err != nil {
		return err
	}
	// 如果是公有的组，则插入一个默认的租户 code ，返回即可
	if po.IsPublic == 1 {
		defaultItem := CustomerGroupTenantRelationPo{
			CustomerGroupID: po.ID,
			TenantCode:      "all",
			IsDeleted:       constants.IsDeletedFalse,
			CreatedBy:       "",
			CreatedOn:       time.Now(),
			ModifiedBy:      "",
			ModifiedOn:      time.Now(),
		}
		err = db.Table(CustomerGroupTenantRelationPo{}.TableName()).Create(&defaultItem).Error
		if err != nil {
			return err
		}
		return nil
	}

	// 如果不是公有的组，则插入租户 code
	if len(tenantCode) == 0 {
		return nil
	}
	var data []CustomerGroupTenantRelationPo
	for _, code := range tenantCode {
		data = append(data, CustomerGroupTenantRelationPo{
			CustomerGroupID: po.ID,
			TenantCode:      code,
			IsDeleted:       constants.IsDeletedFalse,
			CreatedBy:       "",
			CreatedOn:       time.Now(),
			ModifiedBy:      "",
			ModifiedOn:      time.Now(),
		})
	}
	err = db.Table(CustomerGroupTenantRelationPo{}.TableName()).Create(data).Error
	if err != nil {
		return err
	}
	return nil
}

func (c *customerGroupRepository) GetCustomerGroupDetail(ctx context.Context, customerGroupId int64) (*CustomerGroupPo, error) {
	db := stark.MySQLConn.Get(ctx)
	var data CustomerGroupPo
	err := db.Table(CustomerGroupPo{}.TableName()).Where("id = ? and is_deleted = ?", customerGroupId, constants.IsDeletedFalse).First(&data).Error
	if err != nil {
		return nil, err
	}
	return &data, nil
}

func (c *customerGroupRepository) GetCustomerGroupTenantRelation(ctx context.Context, customerGroupId int64) ([]string, error) {
	var data []*CustomerGroupTenantRelationPo
	db := stark.MySQLConn.Get(ctx)
	err := db.Table(CustomerGroupTenantRelationPo{}.TableName()).
		Where("is_deleted = ? and customer_group_id = ?", constants.IsDeletedFalse, customerGroupId).
		Find(&data).Error
	result := make([]string, 0)
	if err != nil && err != gorm.ErrRecordNotFound {
		return result, err
	}
	for _, v := range data {
		result = append(result, v.TenantCode)
	}
	return result, nil
}

func (c *customerGroupRepository) DeleteCustomerGroup(ctx context.Context, customerGroupId int64) error {
	db := stark.MySQLConn.Get(ctx)
	err := db.Table(CustomerGroupPo{}.TableName()).
		Where("id = ? and is_deleted = ?", customerGroupId, constants.IsDeletedFalse).
		Update("is_deleted", constants.IsDeletedTrue).Error
	if err != nil {
		return err
	}
	err = db.Table(CustomerGroupTenantRelationPo{}.TableName()).
		Where("is_deleted = ? and customer_group_id = ?", constants.IsDeletedFalse, customerGroupId).
		Update("is_deleted", constants.IsDeletedTrue).
		Error
	if err != nil {
		return err
	}
	return nil
}

func (c *customerGroupRepository) IsRepeatTitle(ctx context.Context, title string, id int64) (bool, error) {
	db := stark.MySQLConn.Get(ctx)
	db = db.Table(CustomerGroupPo{}.TableName()).
		Where("title = ? and is_deleted = ?", title, constants.IsDeletedFalse)
	if id > 0 {
		db = db.Where("id <> ?", id)
	}
	err := db.First(&CustomerGroupPo{}).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		stark.Logger.Errorf(ctx, "IsRepeatTitle error: %v", err)
		return true, err
	} else if err == gorm.ErrRecordNotFound {
		return false, nil
	} else {
		return true, nil
	}
}

func (c *customerGroupRepository) GetAllCustomerGroupIds(ctx context.Context) ([]int64, error) {
	var ids []int64
	err := stark.MySQLConn.Get(ctx).Table(CustomerGroupPo{}.TableName()).Where("is_deleted =?", constants.IsDeletedFalse).Pluck("id", &ids).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, err
	}
	return ids, nil
}

func (c *customerGroupRepository) UpdateCustomerGroupTotalById(ctx context.Context, id int64, total int32) error {
	return stark.MySQLConn.Get(ctx).Table(CustomerGroupPo{}.TableName()).Where("id =?", id).
		Updates(map[string]interface{}{"total": total, "status": 1, "modified_on": time.Now()}).Error
}
